home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / util2 / hexdump.lha / hexdump / hd.c < prev    next >
C/C++ Source or Header  |  1995-11-09  |  9KB  |  353 lines

  1. /******************************************************************************
  2. *
  3. *   Copyright P.J.Ruczynski 1990
  4. *   This software is free for redistribution and re-use as long as this
  5. *   copyright is included in all source files. This software is supplied
  6. *   as is and no responsibilty is taken by the author for any problems
  7. *   arising from this code.
  8. *
  9. * File name        -  hd.c
  10. *
  11. * Module name        -  HD
  12. *
  13. * Author        -  P.J.Ruczynski    <pjr@pyra.co.uk>
  14. *
  15. * First Release        -  16 Feb 1990
  16. *
  17. * Version number    -  1.4
  18. *
  19. * Description        -  A hexdump formatting tool, this can take input from
  20. *               stdin or a file and print it to stdout in a neat
  21. *               hexdump format.
  22. *               Basically, a better/different(*) version of od.
  23. *
  24. *                (*) delete as you think appropriate :-)
  25. *
  26. *            Revision List
  27. *
  28. * pjr   08.05.89        Added offset numbering. 
  29. *
  30. * pjr   11.05.89        Added compressed output format. 
  31. *
  32. * pjr    30.05.89    Changed to allow any block size to be used, default
  33. *            is still 1024 though.
  34. *
  35. * pjr    31.05.89    Added version printing option.
  36. *
  37. * pjr    02.06.89    Added start and end block specification.
  38. *
  39. ******************************************************************************/
  40.  
  41. #define VERSION        "1.4 (14.09.89)"
  42. #define PRINTUSAGE    fprintf(stderr,"Usage: %s [-cnov] [-b n] [-sp|-sn n] [-sb n] [-eb n] [filename]\n", progname);
  43.  
  44. /*
  45.  * This file contains the following routines:
  46.  *
  47.  * main()
  48.  * get_options()
  49.  * openfile()
  50.  * closefile()
  51.  */
  52.  
  53. #include <stdio.h>
  54. #include <sys/types.h>
  55. #include <sys/file.h>
  56. #include <string.h>
  57. #include <fcntl.h>
  58. #include "hexprint.h"
  59.  
  60. #define    MAXLINE        256    /* Length of character strings. */
  61. #define    MAX_BUFSIZ    1024    /* default read bufer size */
  62.  
  63. /*
  64.  * these are control vars for the hexprint routine
  65.  */
  66. extern int offset_print;    /* only print offsets on request */
  67. extern long offset;        /* default start offset for printing */
  68. extern int hex_compression;    /* compress identical lines */
  69.  
  70. /*
  71.  * option variables
  72.  */
  73. char progname[MAXLINE];        /* Name of this program. */
  74. int b_start = 1;        /* start block no to be printed */
  75. int b_end = 0;            /* end block no to be printed */
  76. int b_size = MAX_BUFSIZ;    /* block size */
  77. int blocking_on = FALSE;    /* only block up on request */
  78. char fname[MAXLINE];        /* name of input file (if any) */
  79. int block_numbering = FALSE;    /* output number of each block ? */
  80. int print_start_block = FALSE;    /* print the very first diff size block ? */
  81. int sb_size = 0;        /* staring block size */
  82. long n_blocks = 0;        /* no blocks to print, 0 => all */
  83.  
  84. /*
  85.  * get_options
  86.  *
  87.  * Read and process command line options.
  88.  */
  89. /*****************************************************************************/
  90. void get_options(argc,argv)
  91. /*****************************************************************************/
  92. int argc;
  93. char *argv[];
  94. {
  95. int i;
  96.  
  97.     fname[0] = 0;    /* indicate no filename input */
  98.     argc-- ; argv++ ;    /* skip the program name */
  99.  
  100.     while (argc > 0)    /* now get the rest */
  101.     {
  102.       if (argv[0][0] == '-')
  103.     switch (argv[0][1])
  104.     {
  105.     case 'b' :    /* block size to output */
  106.         argv++;
  107.         b_size = (int)strtol(&argv[0][0], (char **)NULL, 0);
  108.         printf("block size = %d (0x%x) bytes\n",
  109.                 b_size,(unsigned)b_size);
  110.         blocking_on = TRUE;
  111.         argc--;
  112.         break;
  113.     case 'c' :
  114.     case 'n' :
  115.     case 'o' :
  116.     case 'v' :
  117.         i = 1;
  118.         while (argv[0][i])
  119.         {
  120.             switch (argv[0][i])
  121.             {
  122.             case 'c' :    /* compress identical lines */
  123.                 hex_compression = TRUE;
  124.                 break;
  125.             case 'n' :    /* switch on block numbering */
  126.                 block_numbering = TRUE;
  127.                 blocking_on = TRUE;
  128.                 break;
  129.             case 'o' :    /* switch on offset printing */
  130.                 offset_print = TRUE;
  131.                 break;
  132.             case 'v' :    /* print the version of this hd */
  133.                 printf("%s version %s Author P.Ruczynski\n",
  134.                         progname,VERSION);
  135.                 break;
  136.             default : PRINTUSAGE
  137.                 exit(1);
  138.             } /* end of switch */
  139.             i++;
  140.         } /* end of while */
  141.         break;
  142.     case 'e' :    /* end block options */
  143.         switch (argv[0][2])
  144.         {
  145.         case 'b' :    /* do not print starting block */
  146.             argv++;
  147.             b_end = strtol(&argv[0][0], (char **)NULL, 0);
  148.             printf("last block printed = %d (0x%x) bytes\n",
  149.                     b_end,(unsigned)b_end);
  150.             argc--;
  151.             break;
  152.         default: PRINTUSAGE
  153.             exit(1);
  154.         }
  155.         break;
  156.     case 's' :    /* starting block options */
  157.         switch (argv[0][2])
  158.         {
  159.         case 'p' :    /* print the starting block */
  160.             print_start_block = TRUE;
  161.             /* FALL THROUGH */
  162.         case 'n' :    /* do not print starting block */
  163.             argv++;
  164.             sb_size = strtol(&argv[0][0], (char **)NULL, 0);
  165.             printf("starting block size = %d (0x%x) bytes\n",
  166.                     sb_size,(unsigned)sb_size);
  167.             argc--;
  168.             break;
  169.         case 'b' :    /* get the starting block number */
  170.             argv++;
  171.             b_start = strtol(&argv[0][0], (char **)NULL, 0);
  172.             printf("first block printed = %d (0x%x) bytes\n",
  173.                     b_start,(unsigned)b_start);
  174.             argc--;
  175.             break;
  176.         default: PRINTUSAGE
  177.             exit(1);
  178.         }
  179.         break;
  180.     case '?' :
  181.     default  : PRINTUSAGE
  182.         exit(1);
  183.     } /* end of case */
  184.     else    /* not an option so must be file name */
  185.     {
  186.         strcpy(&fname[0], &argv[0][0]);
  187.         printf("input file = %s\n",fname);
  188.     }
  189.  
  190.     argc-- ;
  191.     argv++ ;
  192.  
  193.     } /* end of while loop */
  194.  
  195. } /* end of get_options */
  196.  
  197.  
  198. /*
  199.  * openfile
  200.  *
  201.  * open the requested file or assign stdin for reading
  202.  */
  203. /*****************************************************************************/
  204. int openfile(fname)
  205. /*****************************************************************************/
  206. char *fname;
  207. {
  208. int fd;    /* file descriptor to read from */
  209.  
  210.     if (fname[0] != 0)
  211.         if ((fd = open(fname, O_RDONLY)) < 0)
  212.         {
  213.             perror(progname);
  214.             exit(1);
  215.         }
  216.         else
  217.             return(fd);
  218.     else
  219.         return(0);    /* if no file then stdin */
  220. } /* end of openfile */
  221.  
  222.  
  223. /*
  224.  * closefile
  225.  *
  226.  * close the given file descriptor
  227.  */
  228. /*****************************************************************************/
  229. void closefile(fd)
  230. /*****************************************************************************/
  231. int fd;
  232. {
  233.     if (fd != 0)
  234.         close(fd);
  235. } /* end of closefile */
  236.  
  237.  
  238. /*
  239.  * printfile
  240.  *
  241.  * print the given file descriptor
  242.  */
  243. /*****************************************************************************/
  244. void printfile(fd)
  245. /*****************************************************************************/
  246. int fd;
  247. {
  248. char *buf;    /*[MAX_BUFSIZ]; */
  249. int n, x=0, y=0, i;
  250. long bn = 1;
  251.  
  252.     if ((buf = (char *)malloc(b_size)) == (char *)NULL)
  253.     {
  254.         printf("%s: error in block size memory allocation\n",progname);
  255.         exit(1);
  256.     }
  257.  
  258.     /*
  259.      * this first 'if' handles the start block case (if there is one)
  260.      */
  261.     if (sb_size != 0)
  262.     {
  263.         x = sb_size % MAX_BUFSIZ;    /* the very last bit */
  264.         y = sb_size / MAX_BUFSIZ;    /* the no of full bufs */
  265.         sb_size = MAX_BUFSIZ;        /* optimum read size. 1K */
  266.  
  267.         if ((block_numbering) && (print_start_block))
  268.             printf("start block\n");
  269.  
  270.         for (i=0; i<=y; i++)
  271.         {
  272.             if (i==y)
  273.                 sb_size = x;
  274.  
  275.             if (((n=read(fd, &buf[0], sb_size)) > 0) &&
  276.                     (print_start_block))
  277.                 hexprint(&buf[0], n);
  278.         
  279.             offset += n;
  280.         }
  281.  
  282.         if (((blocking_on) || (hex_compression))
  283.             && (print_start_block))
  284.             printf("\n");
  285.     }
  286.         
  287.     while ((n = read(fd, &buf[0], b_size)) > 0)
  288.     {
  289.         if ((block_numbering) && (bn >= b_start) &&
  290.             ((bn <= b_end) || (b_end == 0)))
  291.         {
  292.             printf("block number %d (0x%x) ", bn, bn);
  293.             if (n < b_size)
  294.                 printf("size = %d",n);
  295.             printf("\n");
  296.         }
  297.  
  298.         if (blocking_on)
  299.         {
  300.             if (bn >= b_start)
  301.             {
  302.                 if (b_end == 0)
  303.                 {
  304.                     hexprint(&buf[0], n);
  305.                     offset += n;
  306.                 }
  307.                 else if (bn <= b_end)
  308.                 {
  309.                     hexprint(&buf[0], n);
  310.                     offset += n;
  311.                 }
  312.             }
  313.             bn++;
  314.         }
  315.         else
  316.         {
  317.             hexprint(&buf[0], n);
  318.             offset += n;
  319.         }
  320.  
  321.         if (((blocking_on) || (hex_compression)) &&
  322.              (bn >= b_start) && ((bn <= b_end) || (b_end == 0)))
  323.             printf("\n");
  324.     }
  325.  
  326.     free(buf);
  327.  
  328. } /* end of printfile */
  329.  
  330. /*
  331.  * main
  332.  */
  333. /*****************************************************************************/
  334. main(argc,argv)
  335. /*****************************************************************************/
  336. int argc;
  337. char **argv;
  338. {
  339. int fd;    /* file descriptor to read from */
  340.  
  341.     strcpy(progname, argv[0]);  /* Save this program name. */
  342.     get_options(argc,argv);     /* Read and process command line options. */
  343.  
  344.     fd = openfile(fname);        /* do this cos input maybe stdin */
  345.     printfile(fd);
  346.     closefile(fd);
  347.  
  348.     exit(0);
  349.  
  350. } /* end of main */
  351.  
  352.  
  353.